#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define COMMAND_SIZE 128 
#define MAXARGC 128
char Hostname[256];
char *g_argv[MAXARGC]; 
int g_argc = 0;  

const char *GetUserName()
{
    const char *name = getenv("USER");
    return name == NULL ? "None" : name;
}

const char *GetHostName()
{   
    gethostname(Hostname, sizeof(Hostname));
    return Hostname == NULL ? "None" : Hostname;
}

const char *GetPwd()
{
    const char *pwd = getenv("PWD");
    return pwd == NULL ? "None" : pwd;
}



void PCPt(){
    char prompt[COMMAND_SIZE];
#define FORMAT "[%s@%s %s]# "
    snprintf(prompt,sizeof(prompt),FORMAT,GetUserName(),GetHostName(), GetPwd());
    std::cout<<prompt;
    fflush(stdout);
}

bool GetCommandLine(char *out, int size){
    //分割空格获得字符
    if(fgets(out,size,stdin)==NULL) return false;
    out[strcspn(out, "\n")] = '\0';
    if(strlen(out)==0) return false;
    return true;
}

void CommandParse(char* commandline){
#define sep " "
    g_argc = 0;
    g_argv[g_argc++] = strtok(commandline,sep);
    while((bool)(g_argv[g_argc++] =strtok(nullptr,sep)));
    g_argc--;return;
}
int Execute(){
    pid_t id = fork();
    if(id==0){
        execvp(g_argv[0], g_argv);
        exit(1);
    }

    pid_t rid = waitpid(id,nullptr,0);
    (void)rid;//无意义单纯避免编译器优化
    return 0;
} 
int main()
{
    while(1){
    //1.输出命令行提示符
    PCPt();
    // 2. 获取用户输入的命令                                                                          
    char commandline[COMMAND_SIZE];                                                                                                                                                    
    if(!GetCommandLine(commandline, sizeof(commandline)))                                             
        continue;                                                                                     
    //std::cout<<commandline<<std::endl;                                                                     
    // 3. 命令行分析 "ls -a -l" -> "ls" "-a" "-l"                                                     
    CommandParse(commandline);                                                                      
    //PrintArgv();                                                                                    
                                                                                                         
    // 4. 执行命令                                                                                       
    Execute(); 
    }
    return 0;
}

